﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using YAPL.Language.Ast.Utils;

namespace YAPL.Language.Ast {
	public class FunctionDefExpression : Expression {
		private readonly string _name;
		private readonly List<ParameterExpression> _parameters;
		private readonly CodeBlockExpression _functionBody;
		private readonly Expression _owner;

		public FunctionDefExpression(ExpressionType nodeType, Type type, string name, Expression owner,
				List<ParameterExpression> parameters, 
				CodeBlockExpression functionBody) : base(nodeType, type) {
			_owner = owner;
			_name = name;
			_parameters = parameters;
			_functionBody = functionBody;
		}

		public FunctionDefExpression(ExpressionType nodeType, Type type, bool canRead, bool canWrite, string name, Expression owner,
				List<ParameterExpression> parameters,
				CodeBlockExpression functionBody) : base(nodeType, type, canRead, canWrite) {
			_owner = owner;
			_name = name;
			_parameters = parameters;
			_functionBody = functionBody;
		}

		public string Name {
			get { return _name; }
		}

		[Descendant(AstVisit.AfterCurrent, Priority = 2)]
		public Expression Owner {
			get { return _owner; }
		}

		[Descendant(AstVisit.AfterCurrent, Priority = 1)]
		public List<ParameterExpression> Parameters {
			get { return _parameters; }
		}

		[Descendant(AstVisit.AfterCurrent, Priority = 0)]
		public CodeBlockExpression FunctionBody {
			get { return _functionBody; }
		}



		public override bool NodeEquals(Expression other) {
			if (other is FunctionDefExpression) {
				var otherMethodName = (other as FunctionDefExpression)._name;
				var otherParamCount = (other as FunctionDefExpression)._parameters.Count;
				return _name.Equals(otherMethodName) && _parameters.Count.Equals(otherParamCount);
			}
			return false;
		}

		public override bool RewriteChild(Expression child, Expression newExpression) {
			throw new System.NotImplementedException();
		}
	}
}
